package trunk;

import javafx.animation.Interpolator;
import javafx.animation.Timeline;
import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
/**
 * @author Sidney Harrell
 */
def binaryCounter = BinaryCounter{};
def octalCounter = OctalCounter{};
def decimalCounter = DecimalCounter{};
def hexCounter = HexCounter{};

var time: Integer on replace OldValue{
    binaryCounter.flip(time);
    octalCounter.flip(time);
    decimalCounter.flip(time);
    hexCounter.flip(time);
};

def timer = Timeline {
    keyFrames: [
        at (0s) {time => 0},
        at (6000s) {time => 100000 tween Interpolator.LINEAR }
    ]
};

Stage {
    title: "Counters"
    width: 530
    height: 200
    scene: Scene {
        content: VBox {
            spacing: 10;
            content: [
                binaryCounter
                octalCounter
                decimalCounter
                hexCounter
            ]
        };
    }
}
timer.play();

abstract class Counter extends CustomNode {
    def digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
        "A", "B", "C", "D", "E", "F"];
    var placeValues: Integer[];
    var representation: String[];
    var digitNodes: Text[];
    var temp: Integer;
    var base: Integer;
    var places: Integer;

    public function flip(time:Integer) {
        if (time > placeValues[0] * base) {
            temp=time mod placeValues[0] * base;
        } else {
            temp=time;
        }
        for (i in [0..places]) {
            if ((temp != 0)and(temp / placeValues[i] != 0)) {
                representation[i] = digits[temp / placeValues[i]];
                temp = temp - placeValues[i]*(temp/placeValues[i]);
            } else {
                representation[i] = digits[0];
            };
        };
    };

}
class OctalCounter extends Counter {

    public override function create(): Node {
        base = 8;
        places = 9;
        placeValues = [134217728, 16777216, 2097152, 262144, 32768,
            4096, 512, 64, 8, 1];
        for( i in [0..places]) {insert digits[0] into representation;};
        for (i in [0..6]) {insert Text {font: Font {size: 24}; x: 10, y: 30 content: digits[0]} into digitNodes;};
        for (i in [0..places]) {insert Text {font: Font {size: 24}; x: 10, y: 30 content: bind representation[i]} into digitNodes;};
        insert Text {font: Font {size: 24}; x: 10, y: 30 content: "octal"} into digitNodes;
        return Group {content: HBox{spacing: 10 content:[digitNodes];}};
    }
}

class BinaryCounter extends Counter {
    
    public override function create(): Node {
        base = 2;
        places = 16;
        placeValues = [16384 * 2 * 2, 16384 * 2, 16384, 8192, 4096, 2048, 1024,
            512, 256, 128, 64, 32, 16, 8, 4, 2, 1];
        for( i in [0..places]) {insert digits[0] into representation;};
        for (i in [0..places]) {insert Text {font: Font {size: 24}; x: 10, y: 30 content: bind representation[i]} into digitNodes;};
        insert Text {font: Font {size: 24}; x: 10, y: 30 content: "binary"} into digitNodes;
        return Group {content: HBox{spacing: 10 content:[digitNodes];}};
    }
}

class DecimalCounter extends Counter {

    public override function create(): Node {
        base = 10;
        places = 8;
        placeValues = [100000000, 10000000, 1000000, 100000, 10000, 1000,
            100, 10, 1];
        for( i in [0..places]) {insert digits[0] into representation;};
        for (i in [0..7]) {insert Text {font: Font {size: 24}; x: 10, y: 30 content: digits[0]} into digitNodes;};
        for (i in [0..places]) {insert Text {font: Font {size: 24}; x: 10, y: 30 content: bind representation[i]} into digitNodes;};
        insert Text {font: Font {size: 24}; x: 10, y: 30 content: "decimal"} into digitNodes;
        return Group {content: HBox{spacing: 10 content:[digitNodes];}};
    }
}

class HexCounter extends Counter {

    public override function create(): Node {
        base = 16;
        places = 6;
        placeValues = [16777216, 1048576, 65536, 4096, 256, 16, 1];
        for( i in [0..places]) {insert digits[0] into representation;};
        for (i in [0..9]) {insert Text {font: Font {size: 24}; x: 10, y: 30 content: digits[0]} into digitNodes;};
        for (i in [0..places]) {insert Text {font: Font {size: 24}; x: 10, y: 30 content: bind representation[i]} into digitNodes;};
        insert Text {font: Font {size: 24}; x: 10, y: 30 content: "hex"} into digitNodes;
        return Group {content: HBox{spacing: 10 content:[digitNodes];}}
    }
}
